/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.demo.jna;


import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.WinUser.MSG;

import java.awt.event.KeyEvent;

/**
 * Sample implementation of a low-level keyboard hook on W32.
 */
public class KeyHook {
    private static volatile boolean quit;
    private static HHOOK hhk;
    private static LowLevelKeyboardProc keyboardHook;

    public static void main(String[] args) {
        final User32 lib = User32.INSTANCE;
        /*
        HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        keyboardHook = new LowLevelKeyboardProc() {
            public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
                if (nCode >= 0) {
                    switch (wParam.intValue()) {
//                        case WinUser.WM_KEYUP:
                        case WinUser.WM_KEYDOWN:
//                        case WinUser.WM_SYSKEYUP:
//                        case WinUser.WM_SYSKEYDOWN:
                            System.out.println(KeyboardUtils.isPressed(KeyEvent.VK_ALT));
                            System.out.println(nCode + ":" + wParam + ":" + info.vkCode + ":" + info.dwExtraInfo);
                            if (info.vkCode == 81) {
                                quit = true;
                            }
                    }
                }
                return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
            }
        };
        hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
        */
//        System.out.println(b);
//        System.out.println(lib.RegisterHotKey(null, 10000, User32.MOD_ALT | User32.MOD_CONTROL, KeyEvent.VK_N));
        /*
        System.out.println("Keyboard hook installed, type anywhere, 'q' to quit");
        new Thread() {
            public void run() {
                while (!quit) {
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                    }
                }
                System.err.println("unhook and exit");
                lib.UnhookWindowsHookEx(hhk);
                System.exit(0);
            }
        }.start();
        */

        // This bit never returns from GetMessage
        new Thread() {
            public void run() {
                int result;
                MSG msg = new MSG();
                while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
                    if (result == -1) {
                        System.err.println("error in get message");
                        break;
                    } else {
                        System.out.println(msg.wParam.intValue());
                        System.err.println("got message");
                        lib.TranslateMessage(msg);
                        lib.DispatchMessage(msg);
                    }
                }
            }
        }.start();
        boolean b = lib.RegisterHotKey(null, 1000, User32.MOD_ALT | User32.MOD_CONTROL, KeyEvent.VK_M);
//        lib.UnhookWindowsHookEx(hhk);
//        lib.UnregisterHotKey(null, 1000);
        new Thread() {
            public void run() {
                int result;
                MSG msg = new MSG();
                while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
                    if (result == -1) {
                        System.err.println("error in get message");
                        break;
                    } else {
                        System.out.println(msg.wParam.intValue());
                        System.err.println("got message 3");
                        lib.TranslateMessage(msg);
                        lib.DispatchMessage(msg);
                    }
                }
            }
        }.start();
        MSG msg = new MSG();
        int result;
        while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
            if (result == -1) {
                System.err.println("error in get2 message");
                break;
            } else {
                System.out.println(msg.wParam.intValue());
                System.err.println("got message 2");
                lib.TranslateMessage(msg);
                lib.DispatchMessage(msg);
            }
        }
    }
}
